Business & Activity - Supporting local businesses surrounding Tourist attractions
Authored by: Kruthi Shetty and Vinit Shetty
Duration: 120 mins
Level: Intermediate
Pre-requisite Skills: Python, Data Engineering and Analysis
Scenario

As a tourist I want to make the most of the time in the city of Melbourne and have a more enjoyable and fulfilling experience.
When visiting Melbourne, tourists are often eager to uncover new and exciting places to visit, in order to add depth and interest to their itinerary. By researching lesser-known attractions or asking locals for recommendations, travelers can discover hidden gems that may not have been on their radar initially. Additionally, it's important to plan one's route effectively in order to avoid wasting time and money on unnecessary transportation. By mapping out a logical itinerary, visitors can ensure that they are able to see as much of the city as possible within their allotted time frame, without missing out on any must-see sights.

As a cafe, restaurant, or bistro owner in Melbourne, I understand the value of catering to tourists who are looking to make the most of their time in the city. By recognizing and responding to the needs and interests of visitors, I can build a loyal customer base and create a sustainable business model that benefits both myself and the local tourism industry.
The primary objective of business owners is to enhance customer engagement and drive revenue growth by delivering an exceptional and unforgettable experience to visitors. This can result in a surge of foot traffic and revenue generation for the cafe, restaurant, and bistro owners. In the end, the aim of business owners is to develop a feasible business model that not only serves their best interests but also provides substantial benefits to their customers and the neighboring community.

What Will This Use Case Teach You?

At the end of this use case you will:

  • Learn how to Load the dataset into a Pandas dataframe.
  • Clean the data by removing any unnecessary columns and handling missing values
  • Use the data to create heatmaps to show the density of landmarks or places of interest in different areas of Melbourne
  • Add valuable information about each tourist attractions or place of interest to the visualizations, such as opening hours, ticket prices, and ratings and reviews from previous visitors.
Introduction

Melbourne is known for its vibrant arts and culture scene, with numerous museums, galleries, and theaters. The city is also famous for its food and wine culture, with a diverse range of restaurants, cafes, and bars.It has a thriving coffee culture and is known for its brunch spots. Overall, Melbourne offers a unique combination of culture, food, nature, and sports, making it a popular destination for tourists from around the world.

The objective of this use case is to offer tourists a comprehensive overview of the popular tourist spots and interesting locations in Melbourne, coupled with valuable insights to help them organize their trip effectively. By displaying the attractions on a map, visitors can effortlessly determine their location and proximity to one another, which makes planning their itinerary and optimizing their time in Melbourne a more convenient task. Through the information and guidance provided for each attraction, tourists can make informed decisions regarding which places to visit, which helps them avoid potential disappointments.

Moreover, this use case also benefits the nearby cafes, restaurants, and bistros owners as they will be featured on the map along with the landmarks, leading to an increase in revenue and customer footfall for their establishments.

Datasets List
  • Landmarks and places of interest, including schools, theatres, health services, sports facilities, places of worship, galleries and museums.
  • Public artworks, fountains and monuments.
  • Public memorials and sculptures.
  • Cafe, restaurant and bistro seats.
Roadmap

Contents

  1. Import important Libraries
  2. Connect and Test Datasets
  3. Analysis of Datasets
    • 3.1. Landmarks and Places of Interest
    • 3.2. Public Artworks, Fountains and Monuments
    • 3.3. Public Memorials and Sculptures
    • 3.4. Cafe, Restaurant and Bistro seats
  4. Combining all Visualisations and Data
  5. Findings & Opportunities
  6. Conclusions
  7. Thank You!
1. Import important Libraries
In [1]:
# Standard
import os
import json

# Data import
import requests

# Data manipulation
import pandas as pd


# Plotting 
import plotly.graph_objs as go
import plotly.express as px
import folium
import folium.plugins as plugins
2. Connect and Test datasets
In [2]:
# Landmarks and places of interest data
lan_url = 'https://data.melbourne.vic.gov.au/api/v2/catalog/datasets/landmarks-and-places-of-interest-including-schools-theatres-health-services-spor/exports/json?limit=-1&offset=0&timezone=UTC'
r = requests.get(lan_url)
response = r.json()
lan_data = pd.DataFrame(response)

# Public artworks, fountains and monuments data
pub_url = 'https://data.melbourne.vic.gov.au/api/v2/catalog/datasets/public-artworks-fountains-and-monuments/exports/json?limit=-1&offset=0&timezone=UTC'
r = requests.get(pub_url)
response = r.json()
pub_data = pd.DataFrame(response)

# Public memorials and sculptures data
mem_url = 'https://data.melbourne.vic.gov.au/api/v2/catalog/datasets/public-memorials-and-sculptures/exports/json?limit=-1&offset=0&timezone=UTC'
r = requests.get(mem_url)
response = r.json()
mem_data = pd.DataFrame(response)

# Cafe, restaurant and bistro seats data
cafe_url = 'https://data.melbourne.vic.gov.au/api/v2/catalog/datasets/cafes-and-restaurants-with-seating-capacity/exports/json?limit=-1&offset=0&timezone=UTC'
r = requests.get(cafe_url)
response = r.json()
cafe_data = pd.DataFrame(response)

Next, we will look at one specific dataset to better understand its structure and how we can use it. For this exercise, we will observe the Landmarks and places of interest dataset, specifically, it's first ten rows.

In [3]:
# Print details of data
print(f'The shape of the dataset is:{lan_data.shape}')
print()
print('The first ten rows of this dataset are:')

# Print the first 10 rows of data
lan_data.head(10)
The shape of the dataset is:(242, 4)

The first ten rows of this dataset are:
Out[3]:
theme sub_theme feature_name co_ordinates
0 Place of Worship Church St Francis Church {'lon': 144.962422614541, 'lat': -37.811884783...
1 Place of Worship Church St James Church {'lon': 144.952468571683, 'lat': -37.810128120...
2 Place of Worship Church St Mary's Anglican Church {'lon': 144.953761537074, 'lat': -37.803166367...
3 Place of Worship Church Scots Church {'lon': 144.96855105335, 'lat': -37.8145687802...
4 Place of Worship Church St Michael's Uniting Church {'lon': 144.969174036096, 'lat': -37.814385132...
5 Place of Worship Church Greek Orthodox Church {'lon': 144.978259089269, 'lat': -37.808806466...
6 Place of Worship Church North Melbourne Uniting {'lon': 144.947671538375, 'lat': -37.803553847...
7 Place of Worship Church South Yarra Presbyterian Church {'lon': 144.98562699348, 'lat': -37.8407473645...
8 Place of Worship Synagogue East Melbourne Synagogue {'lon': 144.97422190954, 'lat': -37.809113728917}
9 Transport Transport Terminal Port of Melbourne {'lon': 144.91753432375, 'lat': -37.8137384362...

We can see that there are 242 records and 4 fields describing each record.

Each record can be broken down into the following fields:

theme: Main Theme of the landmark. e.g. Places of Interest.

sub_theme: Exact Identification of the landmark. e.g Church or Synagogue.

feature_name: Name of the landmark. e.g. St Francis Church, East Melbourne Synagogue.

co_ordinates: Data regarding the geographical location of a place, determined by its latitude and longitude.

Awesome! After taking a look at one of the Melbourne datasets we can see the overall structure and contents. Lets now begin our analysis of each individual dataset.

3. Analysis of Datasets

We are now going analyse each individual dataset so we can generate useful information and visualisations about them. This will assist us when producing final interactive maps and predictions later on.

3.1 Landmarks and Places of Interest Dataset¶

Let's first review the dataset by displaying the first five rows of the dataset.

In [4]:
lan_data.head(5)
Out[4]:
theme sub_theme feature_name co_ordinates
0 Place of Worship Church St Francis Church {'lon': 144.962422614541, 'lat': -37.811884783...
1 Place of Worship Church St James Church {'lon': 144.952468571683, 'lat': -37.810128120...
2 Place of Worship Church St Mary's Anglican Church {'lon': 144.953761537074, 'lat': -37.803166367...
3 Place of Worship Church Scots Church {'lon': 144.96855105335, 'lat': -37.8145687802...
4 Place of Worship Church St Michael's Uniting Church {'lon': 144.969174036096, 'lat': -37.814385132...

Renaming the columns for better user experience

In [5]:
lan_data = lan_data.rename(columns={'sub_theme':'Landmark','feature_name': 'name'})

The next step is to extract the latitute and Longitude from the 'co-ordinates' column

In [6]:
# split the coordinates column into separate latitude and longitude columns
lan_data[['longitude', 'latitude']] = lan_data['co_ordinates'].apply(lambda x: pd.Series(eval(str(x))))

Let us drop the redundant columns

In [7]:
lan_data=lan_data.drop(['co_ordinates'], axis = 1)

Let's Visualize Number of Features by Theme.

In [8]:
# Group the data by theme and count the number of features
df_grouped = lan_data.groupby('theme').size().reset_index(name='count')

# Create a bar plot
fig = px.bar(df_grouped, x='theme', y='count', color='theme', color_discrete_sequence=px.colors.qualitative.Safe)

# Set the title and axis labels
fig.update_layout(title_text='Number of Features by Theme', xaxis_title='Theme', yaxis_title='Count')

# Show the plot
fig.show()

Preview of the Cleaned Landmark Dataset

In [9]:
lan_data.head(2)
Out[9]:
theme Landmark name longitude latitude
0 Place of Worship Church St Francis Church 144.962423 -37.811885
1 Place of Worship Church St James Church 144.952469 -37.810128

The dataset has been subjected to pre-processing and Feature Engineering and is now ready for further analysis.

3.2 Public Artworks, Fountains and Monuments Dataset¶

Let's first review the dataset by displaying the first five rows of the dataset.

In [10]:
pub_data.head(5)
Out[10]:
asset_type name xorg xsource address_point artist alternate_name art_date mel_way_ref respective_author structure co_ordinates easting northing
0 Art Blowhole Beveridge Williams Surveyors Field Survey 13 Harbour Esplanade, DOCKLANDS Duncan Stemler None 2005 2E_G8 City of Melbourne Stainless-steel and aluminium sculpture {'lon': 144.946871022845, 'lat': -37.822018216... 319296.29200 5.811946e+06
1 Art Bandstand City of Melbourne MCC - Ortho Image March 2005 - Final 200 Little Collins Street, MELBOURNE George Dodd None 1864 2F_G3 City Of Melbourne Concrete bandstand {'lon': 144.96733868317, 'lat': -37.8140548689... 321078.68900 5.812869e+06
2 Art Federation Bells City of Melbourne MCC - Ground Ortho Image March 2008 Birrarung Marr, MELBOURNE Designers Neil McLachlan and Anton Hasell None 2002 2F_ K6 City of Melbourne Bronze-alloy bells on galvanised-steel poles {'lon': 144.974167165492, 'lat': -37.818673886... 321690.93246 5.812370e+06
3 Art Coat of Arms City of Melbourne MCC - Ortho Image March 2005 - Final 98 Swanston Street, MELBOURNE City of Melbourne None 1992 2F_F4 City Of Melbourne Brass pavement inlay {'lon': 144.966495940551, 'lat': -37.815158293... 321007.16500 5.812745e+06
4 Monument Edmund Fitzgibbon Memorial City of Melbourne MCC - Ortho Image March 2005 - Final 208 St Kilda Road, SOUTHBANK James White None 1908 2F_H9 City Of Melbourne Bronze statue with Harcourt granite pedestal {'lon': 144.970418561306, 'lat': -37.823612211... 321372.86300 5.811815e+06

Let us drop the redundant columns

In [11]:
pub_data.drop(columns=['xorg', 'xsource', 'address_point', 'alternate_name', 'mel_way_ref', 'respective_author', 'easting', 'northing'], inplace=True)
pub_data
Out[11]:
asset_type name artist art_date structure co_ordinates
0 Art Blowhole Duncan Stemler 2005 Stainless-steel and aluminium sculpture {'lon': 144.946871022845, 'lat': -37.822018216...
1 Art Bandstand George Dodd 1864 Concrete bandstand {'lon': 144.96733868317, 'lat': -37.8140548689...
2 Art Federation Bells Designers Neil McLachlan and Anton Hasell 2002 Bronze-alloy bells on galvanised-steel poles {'lon': 144.974167165492, 'lat': -37.818673886...
3 Art Coat of Arms City of Melbourne 1992 Brass pavement inlay {'lon': 144.966495940551, 'lat': -37.815158293...
4 Monument Edmund Fitzgibbon Memorial James White 1908 Bronze statue with Harcourt granite pedestal {'lon': 144.970418561306, 'lat': -37.823612211...
... ... ... ... ... ... ...
256 Art Car Nuggets Patricia Piccinini 2006 Sculptural forms {'lon': 144.949169769731, 'lat': -37.821738462...
257 Art Car Nuggets Patricia Piccinini 2006 Sculptural forms {'lon': 144.949168740276, 'lat': -37.821724474...
258 Art Scar - A Stolen Vision Karen Casey, Craig Charles, Glenn Romanis, Mar... 2001 Wooden pier post and metal sculptures {'lon': 144.959252201884, 'lat': -37.820154739...
259 Monument Sir John Monash William Leslie Bowles 1950 Bronze statue on granite plinth {'lon': 144.97275207638, 'lat': -37.8267733497...
260 Art Scar - A Stolen Vision Karen Casey, Craig Charles, Glenn Romanis, Mar... 2001 Wooden pier post and metal sculptures {'lon': 144.959477986287, 'lat': -37.820104643...

261 rows × 6 columns

The next step is to extract the latitute and Longitude from the 'co-ordinates' column

In [12]:
pub_data[['longitude', 'latitude']] = pub_data['co_ordinates'].apply(lambda x: pd.Series(eval(str(x))))
pub_data=pub_data.drop(['co_ordinates'], axis = 1)

Renaming the columns for better user experience

In [13]:
pub_data = pub_data.rename(columns={'asset_type': 'Landmark', 'art_date':'year', 'structure': 'description'})

Let's Visualize Landmarks by Percentage

In [14]:
# Group by asset type and count the number of occurrences
grouped = pub_data.groupby("Landmark").size().reset_index(name="count")

# Create a pie chart
fig = px.pie(grouped, values="count", names="Landmark")

# Show the chart
fig.show()
In [15]:
pub_data.head(3)
Out[15]:
Landmark name artist year description longitude latitude
0 Art Blowhole Duncan Stemler 2005 Stainless-steel and aluminium sculpture 144.946871 -37.822018
1 Art Bandstand George Dodd 1864 Concrete bandstand 144.967339 -37.814055
2 Art Federation Bells Designers Neil McLachlan and Anton Hasell 2002 Bronze-alloy bells on galvanised-steel poles 144.974167 -37.818674

The dataset has been subjected to pre-processing and Feature Engineering and is now ready for further analysis.

3.3 Public Memorials and Sculptures Dataset¶

Let's first review the dataset by displaying the first five rows of the dataset.

In [16]:
mem_data.head(5)
Out[16]:
description title co_ordinates
0 Arts & Heritage - Memorials - Fountain Coles Fountain {'lon': 144.973483970263, 'lat': -37.809770639...
1 Arts & Heritage - Memorials - Sculpture World War 1 Memorial {'lon': 144.958086476511, 'lat': -37.791550224...
2 Arts & Heritage - Sculpture - Memorial Sir Edward "Weary" Dunlop {'lon': 144.971594258329, 'lat': -37.825309803...
3 Arts & Heritage - Sculpture - Sculpture The Travellers {'lon': 144.962960549385, 'lat': -37.820079378...
4 Arts & Heritage - Memorials - Garden/Sculpture Pioneer Women's Memorial {'lon': 144.976076236026, 'lat': -37.825114779...

Extract the second word after '-' from the 'description' column

In [17]:
mem_data['Landmark'] = mem_data['description'].str.split('-').str[1]
In [18]:
mem_data['Landmark'].unique()
Out[18]:
array([' Memorials ', ' Sculpture ', ' Aurora Sculpture ', ' Memorial',
       ' Federation Bells ', ' Fountain', ' Indigenous',
       ' Speakers Corner ', ' Horology ', ' Unknown', '',
       ' Artwork Commission '], dtype=object)

As we can see, we have extracted the keyword "Landmark" from the description column and stored it as "Landmark" column in the dataset

The next step is to extract the latitute and Longitude from the 'co-ordinates' column

In [19]:
# Convert the 'co_ordinates' column to string datatype
mem_data['co_ordinates'] = mem_data['co_ordinates'].astype(str)

# Extract the latitude and longitude values from the 'co_ordinates' column
mem_data[['longitude', 'latitude']] = mem_data['co_ordinates'].apply(eval).apply(pd.Series)[['lon', 'lat']]

Longitute and Latitute have been extracted from the 'co_ordinates' column, we can go forward and remove the redundant columns from our dataset and Renaming them for better user experience

In [20]:
# Drop the redundant columns
mem_data_new = mem_data.drop(['co_ordinates'], axis=1)

# Renaming the 'title' column to 'name'

mem_data_new = mem_data_new.rename(columns={'title': 'name'})
In [21]:
mem_data_new.head(5)
Out[21]:
description name Landmark longitude latitude
0 Arts & Heritage - Memorials - Fountain Coles Fountain Memorials 144.973484 -37.809771
1 Arts & Heritage - Memorials - Sculpture World War 1 Memorial Memorials 144.958086 -37.791550
2 Arts & Heritage - Sculpture - Memorial Sir Edward "Weary" Dunlop Sculpture 144.971594 -37.825310
3 Arts & Heritage - Sculpture - Sculpture The Travellers Sculpture 144.962961 -37.820079
4 Arts & Heritage - Memorials - Garden/Sculpture Pioneer Women's Memorial Memorials 144.976076 -37.825115

The dataset has been subjected to pre-processing and Feature Engineering and is now ready for further analysis.

3.4 Cafe, Restaurant and Bistro Seats Dataset¶

Let's first review the dataset by displaying the first five rows of the dataset.

In [22]:
cafe_data.head(5)
Out[22]:
census_year block_id property_id base_property_id building_address clue_small_area business_address trading_name industry_anzsic4_code industry_anzsic4_description seating_type number_of_seats longitude latitude location
0 2014 31 102109 102109 612-624 Collins Street MELBOURNE 3000 Melbourne (CBD) Ground , 618B Collins Street MELBOURNE 3000 Choix Creperie Cafe 4511 Cafes and Restaurants Seats - Outdoor 2 144.95435 -37.81868 {'lon': 144.95435, 'lat': -37.81868}
1 2014 31 102109 102109 612-624 Collins Street MELBOURNE 3000 Melbourne (CBD) Ground , 618 Collins Street MELBOURNE 3000 Purple Peanuts Japanese Cafe 4511 Cafes and Restaurants Seats - Indoor 14 144.95435 -37.81868 {'lon': 144.95435, 'lat': -37.81868}
2 2014 31 102110 102110 582-606 Collins Street MELBOURNE 3000 Melbourne (CBD) Shop 1, 600 Collins Street MELBOURNE 3000 Cafe Eurasia 4511 Cafes and Restaurants Seats - Outdoor 14 144.95494 -37.81850 {'lon': 144.95494, 'lat': -37.8185}
3 2014 31 102111 102111 608-610 Collins Street MELBOURNE 3000 Melbourne (CBD) Shop 5, 608-610 Collins Street MELBOURNE 3000 Wonderful Garden 4512 Takeaway Food Services Seats - Outdoor 5 144.95457 -37.81861 {'lon': 144.95457, 'lat': -37.81861}
4 2014 31 105942 105942 585-587 Little Collins Street MELBOURNE 3000 Melbourne (CBD) 585 Little Collins Street MELBOURNE 3000 Hudson & Co 4512 Takeaway Food Services Seats - Indoor 16 144.95544 -37.81787 {'lon': 144.95544, 'lat': -37.81787}

Check for Null Values in Dataset

In [23]:
cafe_data.isnull().sum()
Out[23]:
census_year                       0
block_id                          0
property_id                       0
base_property_id                  0
building_address                  0
clue_small_area                   0
business_address                  0
trading_name                      0
industry_anzsic4_code             0
industry_anzsic4_description      0
seating_type                      0
number_of_seats                   0
longitude                       527
latitude                        527
location                        527
dtype: int64

Drop the Null values

cafe_data.dropna(inplace = True)

Let us drop the redundant columns and rename some of the columns for better user experience

In [24]:
# Drop redundant Data

cafe_data = cafe_data.drop(['block_id', 'property_id','base_property_id','business_address','clue_small_area',
                            'industry_anzsic4_code','location'], axis=1)

#Rename some of the columns

cafe_data = cafe_data.rename(columns={'trading_name': 'name','building_address':'address','census_year':'year',
                                      'industry_anzsic4_description':'Industry'})

Drop Duplicate Values based on the column "Name"

In [25]:
cafe_data = cafe_data.drop_duplicates(subset=['name'])
cafe_data
Out[25]:
year address name Industry seating_type number_of_seats longitude latitude
0 2014 612-624 Collins Street MELBOURNE 3000 Choix Creperie Cafe Cafes and Restaurants Seats - Outdoor 2 144.95435 -37.81868
1 2014 612-624 Collins Street MELBOURNE 3000 Purple Peanuts Japanese Cafe Cafes and Restaurants Seats - Indoor 14 144.95435 -37.81868
2 2014 582-606 Collins Street MELBOURNE 3000 Cafe Eurasia Cafes and Restaurants Seats - Outdoor 14 144.95494 -37.81850
3 2014 608-610 Collins Street MELBOURNE 3000 Wonderful Garden Takeaway Food Services Seats - Outdoor 5 144.95457 -37.81861
4 2014 585-587 Little Collins Street MELBOURNE 3000 Hudson & Co Takeaway Food Services Seats - Indoor 16 144.95544 -37.81787
... ... ... ... ... ... ... ... ...
56930 2021 697 Collins Street DOCKLANDS VIC 3008 Destination Roll Takeaway Food Services Seats - Indoor 7 144.95177 -37.82079
56940 2021 829-843 Bourke Street DOCKLANDS VIC 3008 San Marzano Pizzeria Takeaway Food Services Seats - Indoor 8 144.94346 -37.82045
56944 2021 Serrata Apartments 813-817 Bourke Street DOCKL... TOSS'D Cafes and Restaurants Seats - Outdoor 22 144.94469 -37.81995
56948 2021 790-814 Collins Street DOCKLANDS VIC 3008 Poke Bay Takeaway Food Services Seats - Indoor 6 144.94583 -37.82104
56961 2021 The District Docklands East Car Park 50-94 Wat... Shall We Coffee Takeaway Food Services Seats - Outdoor 6 144.93944 -37.81215

6328 rows × 8 columns

Categorised some of the Industries as "Other", if their total count is less than 150 as they will be of less importance for our analysis

In [26]:
# Compute the value counts of the 'industry_anzsic4_description' column
counts = cafe_data['Industry'].value_counts()

# Replace values that have counts less than 150 with 'Other'
cafe_data.loc[cafe_data['Industry'].isin(counts[counts < 260].index), 'Industry'] = 'Other'
count = cafe_data['Industry'].value_counts()

Created a dataframe which contains the Industry name and the total count in City of Melbourne

In [27]:
# create a new dataframe to store the counts
counts_df = pd.DataFrame(count, count.index).reset_index()
counts_df.columns = ['Industry', 'count']
In [28]:
counts_df
Out[28]:
Industry count
0 Cafes and Restaurants 4544
1 Takeaway Food Services 979
2 Other 418
3 Pubs, Taverns and Bars 387

Lets Visualize a Pie Chart for the Industry-Count data.

In [29]:
import plotly.graph_objs as go

# create a pie chart
fig = go.Figure(
    go.Pie(
        labels=counts_df['Industry'],
        values=counts_df['count']
    )
)

# set the title
fig.update_layout(title_text='Top Industries by Count')

# show the plot
fig.show()

Final dataset

In [30]:
cafe_data.head(3)
Out[30]:
year address name Industry seating_type number_of_seats longitude latitude
0 2014 612-624 Collins Street MELBOURNE 3000 Choix Creperie Cafe Cafes and Restaurants Seats - Outdoor 2 144.95435 -37.81868
1 2014 612-624 Collins Street MELBOURNE 3000 Purple Peanuts Japanese Cafe Cafes and Restaurants Seats - Indoor 14 144.95435 -37.81868
2 2014 582-606 Collins Street MELBOURNE 3000 Cafe Eurasia Cafes and Restaurants Seats - Outdoor 14 144.95494 -37.81850
In [31]:
#cafe_data = cafe_data.head(50)

The dataset has been subjected to pre-processing and Feature Engineering and is now ready for further analysis.

4. Combining all Visualisations and Data
In [32]:
df1_merged = pd.merge(lan_data, pub_data, on=['Landmark', 'name', 'longitude','latitude'],how='outer')
In [33]:
combined_df = pd.merge(df1_merged, mem_data_new, on=['Landmark', 'name', 'longitude','latitude','description'],how='outer')

Fill the null Values with "N.A"

In [34]:
combined_df_cleaned = combined_df.fillna('N.A')
combined_df_cleaned
Out[34]:
theme Landmark name longitude latitude artist year description
0 Place of Worship Church St Francis Church 144.962423 -37.811885 N.A N.A N.A
1 Place of Worship Church St James Church 144.952469 -37.810128 N.A N.A N.A
2 Place of Worship Church St Mary's Anglican Church 144.953762 -37.803166 N.A N.A N.A
3 Place of Worship Church Scots Church 144.968551 -37.814569 N.A N.A N.A
4 Place of Worship Church St Michael's Uniting Church 144.969174 -37.814385 N.A N.A N.A
... ... ... ... ... ... ... ... ...
661 N.A Memorials Sir William Brunton Drinking Fountain 144.972179 -37.789304 N.A N.A Arts & Heritage - Memorials - Drinking Fountain
662 N.A Artwork Commission Maxims of Behaviour 144.965809 -37.813602 N.A N.A Art & Heritage Collection - Artwork Commission...
663 N.A Sculpture Another View Site 17 144.968381 -37.814805 N.A N.A Arts & Heritage - Sculpture - Sculpture
664 N.A Sculpture Vault 144.967733 -37.826071 N.A N.A Arts & Heritage - Sculpture - Sculpture
665 N.A Sculpture Commonwealth Games Aquatic Sculptures - Eels 144.924307 -37.796629 N.A N.A Art and Heritage - Sculpture - Commonwealth Ga...

666 rows × 8 columns

Remove duplicates based on the column "name"

In [35]:
combined_df_final = combined_df_cleaned.drop_duplicates(subset=['name'])
combined_df_final
Out[35]:
theme Landmark name longitude latitude artist year description
0 Place of Worship Church St Francis Church 144.962423 -37.811885 N.A N.A N.A
1 Place of Worship Church St James Church 144.952469 -37.810128 N.A N.A N.A
2 Place of Worship Church St Mary's Anglican Church 144.953762 -37.803166 N.A N.A N.A
3 Place of Worship Church Scots Church 144.968551 -37.814569 N.A N.A N.A
4 Place of Worship Church St Michael's Uniting Church 144.969174 -37.814385 N.A N.A N.A
... ... ... ... ... ... ... ... ...
651 N.A Memorials Australian Hellenic Memorial 144.972974 -37.827212 N.A N.A Arts & Heritage - Memorials - Memorial
653 N.A Sculpture Nurse Edith Cavell Memorial 144.973699 -37.827988 N.A N.A Arts & Heritage - Sculpture - Sculpture
655 N.A Memorials Victoria Police Memorial 144.970982 -37.824242 N.A N.A Arts & Heritage - Memorials - Memorial
661 N.A Memorials Sir William Brunton Drinking Fountain 144.972179 -37.789304 N.A N.A Arts & Heritage - Memorials - Drinking Fountain
663 N.A Sculpture Another View Site 17 144.968381 -37.814805 N.A N.A Arts & Heritage - Sculpture - Sculpture

449 rows × 8 columns

Create Dictionary for Custom Icons and Colors for Landmarks and Cafes & Restaurants

In [36]:
icons = {
    'Church': {'icon': 'church', 'color': 'blue'},
    'Synagogue': {'icon': 'star-of-david', 'color': 'purple'},
    'Transport Terminal': {'icon': 'bus', 'color': 'darkblue'},
    'Major Sports & Recreation Facility': {'icon': 'futbol', 'color': 'orange'},
    'Primary Schools': {'icon': 'graduation-cap', 'color': 'green'},
    'Informal Outdoor Facility (Park/Garden/Reserve)': {'icon': 'tree', 'color': 'green'},
    'Secondary Schools': {'icon': 'graduation-cap', 'color': 'green'},
    'Theatre Live': {'icon': 'ticket', 'color': 'red'},
    'Retail/Office': {'icon': 'shopping-cart', 'color': 'gray'},
    'Private Hospital': {'icon': 'hospital', 'color': 'red'},
    'Government Building': {'icon': 'institution', 'color': 'darkpurple'},
    'Railway Station': {'icon': 'train', 'color': 'black'},
    'Vacant Land - Undeveloped Site': {'icon': 'ban', 'color': 'gray'},
    'Retail/Office/Carpark': {'icon': 'building', 'color': 'gray'},
    'Art Gallery/Museum': {'icon': 'image', 'color': 'red'},
    'Office': {'icon': 'briefcase', 'color': 'gray'},
    'Film & RV Studio': {'icon': 'video-camera', 'color': 'lightblue'},
    'Marina': {'icon': 'anchor', 'color': 'blue'},
    'Public Hospital': {'icon': 'hospital', 'color': 'red'},
    'Hostel': {'icon': 'bed', 'color': 'black'},
    'Outdoor Recreation Facility (Zoo, Golf Course)': {'icon': 'paw', 'color': 'green'},
    'Public Buildings': {'icon': 'home', 'color': 'darkpurple'},
    'Tertiary (University)': {'icon': 'university', 'color': 'darkpurple'},
    'Fire Station': {'icon': 'fire-extinguisher', 'color': 'red'},
    'Observation Tower/Wheel': {'icon': 'eye', 'color': 'gray'},
    'Dwelling (House)': {'icon': 'home', 'color': 'black'},
    'Police Station': {'icon': 'shield', 'color': 'red'},
    'Private Sports Club/Facility': {'icon': 'futbol', 'color': 'orange'},
    'Function/Conference/Exhibition Centre': {'icon': 'briefcase', 'color': 'red'},
    'Current Construction Site': {'icon': 'hard-hat', 'color': 'gray'},
    'Further Education': {'icon': 'book', 'color': 'darkpurple'},
    'Indoor Recreation Facility': {'icon': 'cube', 'color': 'orange'},
    'Store Yard': {'icon': 'building', 'color': 'gray'},
    'Retail/Office/Residential/Carpark': {'icon': 'home', 'color': 'gray'},
    'Gymnasium/Health Club': {'icon': 'heartbeat', 'color': 'orange'},
    'Retail/Residential': {'icon': 'home', 'color': 'black'},
    'Visitor Centre': {'icon': 'binoculars', 'color': 'gray'},
    'Library': {'icon': 'book', 'color': 'purple'},
    'Cemetery': {'icon': 'cross', 'color': 'gray'},
    'Retail': {'icon': 'shopping-cart', 'color': 'blue'},
    'School - Primary and Secondary Education': {'icon': 'graduation-cap', 'color': 'orange'},
    'Casino': {'icon': 'diamond', 'color': 'red'},
    'Current Construction Site - Commercial': {'icon': 'hard-hat', 'color': 'darkblue'},
    'Cinema': {'icon': 'film', 'color': 'green'},
    'Industrial (Manufacturing)': {'icon': 'industry', 'color': 'black'},
    'Aquarium': {'icon': 'fish', 'color': 'darkgreen'},
    'Bridge': {'icon': 'bridge', 'color': 'pink'},
    'Department Store': {'icon': 'shopping-bag', 'color': 'cadetblue'},
    'Medical Services': {'icon': 'ambulance', 'color': 'lightred'},
    'Art': {'icon': 'paint-brush', 'color': 'darkpurple'},
    'Monument': {'icon': 'monument', 'color': 'darkgreen'},
    'Fountain': {'icon': 'volcano', 'color': 'lightblue'},
    ' Memorials ': {'icon': 'monument', 'color': 'darkred'},
    ' Sculpture ': {'icon': 'landmark', 'color': 'purple'},
    ' Aurora Sculpture ': {'icon': 'snowflake', 'color': 'darkgreen'},
    ' Memorial': {'icon': 'monument', 'color': 'darkred'},
    ' Federation Bells ': {'icon': 'music', 'color': 'darkpurple'},
    ' Indigenous': {'icon': 'leaf', 'color': 'orange'},
    ' Speakers Corner ': {'icon': 'bullhorn', 'color': 'gray'},
    ' Horology ': {'icon': 'clock', 'color': 'black'},
    ' Unknown': {'icon': 'question-circle', 'color': 'gray'},
    '': {'icon': 'question-circle', 'color': 'gray'},
    ' Artwork Commission ': {'icon': 'paint-brush', 'color': 'darkpurple'}
}
In [37]:
icon_cafe = {
    'Cafes and Restaurants': {'icon': 'coffee', 'color': 'red'},
    'Takeaway Food Services': {'icon': 'utensils', 'color': 'purple'},
    'Pubs, Taverns and Bars': {'icon': 'wine-glass', 'color': 'darkblue'},
    'Other': {'icon': 'question-circle', 'color': 'black'}
}

Visualizing a Map which Displays the Landmarks and the Cafes,Restaurants and Bars Nearby

In [38]:
# Create a map object centered on Melbourne, Australia
melbourne_map = folium.Map(location=[-37.8136, 144.9631], zoom_start=20, width='100%', height='100%')

marker_group = folium.FeatureGroup(name='Landmarks')
cafe_group = folium.FeatureGroup(name='Cafes')

# Loop through each row in the dataframe
for index, row in combined_df_final.iterrows():
    # Get the landmark type for the current row
    landmark_type = row['Landmark']
    
    # Check if the landmark type is in the icons dictionary
    if landmark_type in icons:
        icon = icons[landmark_type]['icon']
        color = icons[landmark_type]['color']
        
    # Create a list to store nearby cafes
    nearby_cafes = []
    
    # Loop through the cafe data and add nearby cafes to the list
    for cafe_index, cafe_row in cafe_data.iterrows():
        industry_type = cafe_row['Industry']
        if industry_type in icon_cafe:
            icons_cafe = icon_cafe[industry_type]['icon']
            colors_cafe = icon_cafe[industry_type]['color']
        if abs(cafe_row['latitude'] - row['latitude']) < 0.001 and abs(cafe_row['longitude'] - row['longitude']) < 0.001:
            nearby_cafes.append(cafe_row['name'])
            cafe_marker = folium.Marker(
                location=[cafe_row['latitude'], cafe_row['longitude']],
                icon=folium.Icon(color= colors_cafe, icon=icons_cafe, prefix='fa'),
                popup=folium.Popup(
                    f"Name: {cafe_row['name']}<br>Address: {cafe_row['address']}<br>Industry: {cafe_row['Industry']}<br>Seating type: {cafe_row['seating_type']}<br>Number of seats: {cafe_row['number_of_seats']}",
                    max_width=400,
                    style={
                        'font-size': '16px',
                        'line-height': '1.6',
                        'padding': '10px'
                    }
                ),
                tooltip=cafe_row['name']
            )
            cafe_marker.add_to(cafe_group)
    
    # Create a popup HTML string for the landmark
    landmark_popup_html = f"Name: {row['name']}<br>Landmark: {row['Landmark']}<br>Description: {row['description']}"
    
    # Check if there are nearby cafes
    if len(nearby_cafes) > 0:
        # Add nearby cafes to the popup HTML string
        landmark_popup_html += "<br><br><b>Nearby Food Outlets:</b><br>"
        for cafe in nearby_cafes:
            landmark_popup_html += f"{cafe}<br>"
    
    # Create a marker for the landmark
    landmark_marker = folium.Marker(
        location=[row['latitude'], row['longitude']],
        icon = folium.Icon(icon = icon,color = color,prefix = 'fa'),
        popup=folium.Popup(html=landmark_popup_html, max_width=400),
        tooltip=row['name'])
    
    # Add the marker to the map
    landmark_marker.add_to(marker_group)
In [39]:
# Create a legend
legend_html = """
     <div style="position: fixed; 
             bottom: 50px; left: 50px; width: 500px; height: 50px; 
             border:2px solid grey; font-size:4px;
             background-color: white;">
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-church" style="color:blue"></i>&nbsp; Church</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-synagogue" style="color:gray"></i>&nbsp; Synagogue</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-bus" style="color:green"></i>&nbsp; Transport</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-football-ball" style="color:orange"></i>&nbsp; Major Sports & Recreation Facility</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-graduation-cap" style="color:green"></i>&nbsp; Primary Schools</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-tree" style="color:green"></i>&nbsp; Informal Outdoor Facility (Park/Garden/Reserve)</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-graduation-cap" style="color:green"></i>&nbsp; Secondary Schools</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-theater-masks" style="color:red"></i>&nbsp; Theatre Live</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-store" style="color:gray"></i>&nbsp; Retail/Office</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-hospital" style="color:red"></i>&nbsp; Private Hospital</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-university" style="color:darkpurple"></i>&nbsp; Government Building</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-train" style="color:black"></i>&nbsp; Railway Station</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-cubes" style="color:gray"></i>&nbsp; Vacant Land - Undeveloped Site</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-building" style="color:gray"></i>&nbsp; Retail/Office/Carpark</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-palette" style="color:red"></i>&nbsp; Art Gallery/Museum</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-building" style="color:gray"></i>&nbsp; Office</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-film" style="color:lightblue"></i>&nbsp; Film & RV Studio</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-anchor" style="color:blue"></i>&nbsp; Marina</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-hospital" style="color:red"></i>&nbsp; Public Hospital</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-hotel" style="color:black"></i>&nbsp; Hostel</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-paw" style="color:green"></i>&nbsp; Outdoor Recreation Facility (Zoo, Golf Course)</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-house" style="color:darkpurple"></i>&nbsp; Public Buildings</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-university" style="color:darkpurple"></i>&nbsp; University</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-fire-extinguisher" style="color:red"></i>&nbsp; Fire Station</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-eye" style="color:gray"></i>&nbsp; Observation Tower/Wheel</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-home" style="color:black"></i>&nbsp; Dwelling (House)</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-shield" style="color:red"></i>&nbsp; Police Station</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-football-ball" style="color:orange"></i>&nbsp; Private Sports Club/Facility</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-briefcase" style="color:red"></i>&nbsp; Function/Conference/Exhibition Centre</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-helmet-safety" style="color:gray"></i>&nbsp; Current Construction Site</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-book" style="color:darkpurple"></i>&nbsp; Further Education</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-cube" style="color:orange"></i>&nbsp; Indoor Recreation Facility</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-store" style="color:gray"></i>&nbsp; Store Yard</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-building" style="color:gray"></i>&nbsp; Retail/Office/Residential/Carpark</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-dumbbell" style="color:orange"></i>&nbsp; Gymnasium/Health Club</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-building" style="color:black"></i>&nbsp; Retail/Residential</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-info-circle" style="color:gray"></i>&nbsp; Visitor Centre</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-book" style="color:purple"></i>&nbsp; Library</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-cemetery" style="color:gray"></i>&nbsp; Cemetery</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-cross" style="color:blue"></i>&nbsp; Retail</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-school" style="color:orange"></i>&nbsp; School - Primary and Secondary Education</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-dice" style="color:red"></i>&nbsp; Casino</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-helmet-safety" style="color:darkblue"></i>&nbsp; Current Construction Site - Commercial</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-film" style="color:green"></i>&nbsp; Cinema</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-industry" style="color:black"></i>&nbsp; Industrial (Manufacturing)</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-water" style="color:darkgreen"></i>&nbsp; Aquarium</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-road-bridge" style="color:pink"></i>&nbsp; Bridge</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-store" style="color:cadetblue"></i>&nbsp; Department Store</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-hospital" style="color:lightred"></i>&nbsp; Medical Services</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-paint-brush" style="color:darkpurple"></i>&nbsp; Art</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-monument" style="color:darkgreen"></i>&nbsp; Monument</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-volcano" style="color:lightblue"></i>&nbsp; Fountain</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-monument" style="color:darkred"></i>&nbsp; Memorials</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-landmark" style="color:purple"></i>&nbsp; Sculpture</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-snowflake" style="color:darkgreen"></i>&nbsp; Aurora Sculpture</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-monument" style="color:darkred"></i>&nbsp; Memorial</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-bell" style="color:darkpurple"></i>&nbsp; Federation Bells</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-shield-virus" style="color:orange"></i>&nbsp; Indigenous</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-comment-alt" style="color:gray"></i>&nbsp; Speakers Corner</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-clock" style="color:black"></i>&nbsp; Horology</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-question" style="color:gray"></i>&nbsp; Unknown</p>
     <p style="margin:10px; display:inline-block;"><i class="fa-solid fa-paint-brush" style="color:darkpurple"></i>&nbsp; Artwork Commission</p>
     </div>
     """
In [40]:
# Add the feature group to the map
marker_group.add_to(melbourne_map)
cafe_group.add_to(melbourne_map)
folium.LayerControl().add_to(melbourne_map)

# Add the legend to the map
legend = folium.plugins.FloatImage(legend_html, bottom=80, left=50)
legend.add_to(melbourne_map)
Out[40]:
<folium.plugins.float_image.FloatImage at 0x7f9e1096c610>
In [41]:
# Display the map
melbourne_map
Out[41]:
Make this Notebook Trusted to load map: File -> Trust Notebook

We have accomplished the task of generating a map that exhibits the various landmarks and adjacent food establishments such as Cafes, Restaurants, Bars, and Takeaway Food outlets. By selecting a specific location on the map, we can view a compilation of the nearby Cafes, Restaurants, and Bars. To switch between the display of Landmarks and Food outlets, we can utilize the Layer Button situated on the upper right-hand corner of the map.

5. Findings and Opportunities
  • Melbourne is renowned for its unique blend of food, wine, art, and culture, making it a popular tourist destination. By using a map to locate attractions, visitors can plan their itinerary and maximize their time in the city, while also researching to avoid potential disappointments. Including nearby cafes, restaurants, and bistros on the map can also increase sales and patronage at these businesses.
  • To provide more comprehensive guides for visitors to Melbourne, information on transportation, accommodation options, and nearby events and festivals can be included. Food and beverage businesses in the city can capitalize on its popular coffee and brunch culture by offering innovative and distinctive menu options.
  • Personalized travel recommendations based on visitors' interests, preferences, and past travel experiences can be created using data analytics and machine learning. Collaborating with regional tour operators and travel companies can help promote Melbourne's attractions and position the city as a desirable travel destination.
  • Incorporating augmented reality and virtual reality technology to provide immersive and engaging experiences of the city's landmarks can enhance the tourist experience.
6. Conclusion
  • To sum up, utilizing a map-based application to display nearby eateries and tourist hotspots in Melbourne is a helpful tool for assisting visitors in planning their trip and maximizing their time there. By visualizing the proximity and locations of popular tourist attractions and restaurants, visitors can make informed decisions and avoid potential disappointments. In addition, by highlighting local cafes and restaurants on the map, it also benefits the businesses' owners by increasing their visibility and foot traffic.

  • This use case highlights the importance of leveraging technology to improve the tourist experience and support local businesses. As more travelers turn to digital tools to plan their trips, the tourism industry will need to devise innovative solutions that offer valuable information and guidance. Furthermore, as cities evolve and change, regularly updating the information and insights presented on these digital platforms will be crucial to ensure that tourists have the most relevant and accurate information to plan their trips effectively.

7. Thank You

Awesome work. The interactive map is now complete, and we can click on the locations to see relevant Landmarks and nearby Cafes,Restaurants and Bistros metrics around Melbourne. Thank you for your time!